home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-04 / inter36d.zip / INT2HLP.BAT < prev    next >
DOS Batch File  |  1993-08-01  |  15KB  |  561 lines

  1. @REM=("
  2. @perl -w %0.bat %1 %2 %3 %4 %5 %6 %7 %8 %9
  3. @end ") if 0 ;
  4. #
  5. # Create an RTF file from the PC interrupt list.
  6. # The RTF file will be compiled into quickhelp format.
  7. # By Diomidis Spinellis <dds@doc.ic.ac.uk>.
  8. #
  9. # You will need the Microsoft helpmake utility, a sort that takes the -f (fold)
  10. # and -d (dictionary order) options, around 12:40 time of 20MHz 386 CPU 
  11. # time and around 6 MB of disk space.
  12. # Put all the interrupt list distribution files in one directory create the
  13. # interrupt.lst file by merging interrupt.? and run the  program.  The 
  14. # interrupt.lst file will be deleted during the process to save disk space.
  15. #
  16. # (C) Copyright 1991 Diomidis Spinellis.  All rights reserved.
  17. # Permission to use and distribute this file without modification is given.
  18. #
  19. # Updates by David Woolley <100121.53@compuserve.com> to handle category
  20. # letters in Release 34 and later versions of the interrupt list.
  21.  
  22. $labelnum = 0;
  23. # int.byf - Interrupts by Function (Tree Internal Nodes)
  24. &maketop_by_function();
  25. &makecont(0, "Interrupts by Function", "int.byfunc", "int.hlp");
  26. &merge_out('int.byf');
  27. # int.byv - Interrupts by Value (Tree Internal Nodes)
  28. &maketop_by_value();
  29. &makecont(0, "Interrupts by Value", "int.byval", "int.hlp");
  30. &merge_out('int.byv');
  31. # int.bot - Interrupt List Interrupts (Tree Terminal Nodes)
  32. &summary('int.byv', 'sum.byv');
  33. &summary('int.byf', 'sum.byf');
  34. &makebottom();
  35. &unlink_intermediate();
  36. unlink('interrup.lst');    # To make room
  37. # int.idx - Interrupt List Index
  38. &makeindex();
  39. # int.fil - Interrupt List Auxiliary Files
  40. unlink('int.fil');
  41. &incfile('int.mem', 'Memory List', 'memory.lst');
  42. &incfile('int.pri', 'Interrupt Primer', 'interrup.pri');
  43. &make1st();
  44. #&incfile('int.1st', 'Distribution, Abbreviations and Acknowledgements', 'interrup.1st');
  45. # int.toc - Interupt List Table of Contents
  46. &maketoc();
  47. exec('helpmake', '/T', '/e', '/W100', '/oint.hlp', '/V', 'int.toc', 'int.byv', 'int.byf', 'int.bot', 'int.idx', 'int.fil');
  48.  
  49. # Create a contents file.  Level is the recursive level, topic the
  50. # header to use, context the unique identifier for this topic and
  51. # up the identifier of the parent topic.
  52. # Works by scanning the input of the current level line by line and
  53. # identifying topics.  If the topic is unique it is output on a list
  54. # else the topic is output on the list with a pointer to another list
  55. # and the function is called recursively.
  56. sub makecont
  57. {
  58.     local($level, $topic, $context, $up) = @_;
  59.     local($IN, $OUT);
  60.     local($l, $prev, $part, $ref, $tmp);
  61.  
  62.     $IN = "IN$level";
  63.     $OUT = "OUT$level";
  64.     open($IN, "sort in$level|") || die;
  65.     open($OUT, ">>out$level") || die;
  66.  
  67.     print "makecont($level, [$topic], [$context], [$up])\n";
  68.     $dummy = &makehead($context, 3, $topic, $up);
  69.     print $OUT $dummy;
  70.     while (<$IN>) {
  71.         chop;
  72.         print "$level: Read [$_]\n";
  73.         $part = (split(/ \- /))[0];
  74.         if ($part =~ /^`/) {
  75.             $part =~ s/`//;
  76.         } else {
  77.             $part =~ s/`.*//;
  78.         }
  79.         next if ($part eq $prev);
  80.         $ref = (split(/`/))[1];
  81.         print "part = [$part]\n";
  82.         if (&count($part, "in$level") <= 1) {
  83.             if ($ref eq '') {
  84.                 print $OUT "\t\\a$part\\v$part\\v\n";
  85.             } else {
  86.                 print $OUT "\t\\a$part\\v$ref\\v\n";
  87.             }
  88.         } else {
  89.             $u = &newlabel();
  90.             print $OUT "\t\\a$part\\v$u\\v\n";
  91.             $l = $level + 1;
  92.             ©match($part, "in$level", "in$l");
  93.             $tmp = $context;
  94.             &makecont($l, $part, $u, $tmp);
  95.         }
  96.         $prev = $part;
  97.     }
  98.     print $OUT ' ' x 35 . "-\04-\n";
  99.     close($IN);
  100.     close($OUT);
  101. }
  102.  
  103. # Return number of lines matching string
  104. sub count
  105. {
  106.     local($string, $file) = @_;
  107.  
  108.     $string =~ s/(\W)/\\$1/g;
  109.     open (CIN, $file) || die;
  110.     $count = 0;
  111.     while (<CIN>) {
  112.         $count++ if (/^$string(( - )|`)/);
  113.     }
  114.     print "count($string) = $count\n";
  115.     close(CIN);
  116.     return $count;
  117. }
  118.  
  119. # Copy lines that match string from $in to $out removing string
  120. sub copymatch
  121. {
  122.     local($string, $in, $out) = @_;
  123.  
  124.     $string =~ s/(\W)/\\$1/g;
  125.     open(CIN, $in) || die;
  126.     open(COUT, ">$out") || die;
  127.     while (<CIN>) {
  128.         if (/^$string(( - )|`)/) {
  129.             s/^$string[-\s`]*//;
  130.             print COUT;
  131.         }
  132.     }
  133.     close(CIN);
  134.     close(COUT);
  135. }
  136.  
  137. # Open the interrupt list and create a file with one line for each
  138. # interrupt.  The line consists of the interrupt description followed
  139. # by a backtick and the interrupt number.
  140. sub maketop_by_function
  141. {
  142.     &unlink_out();
  143.     open(IN, "interrup.lst") || die;
  144.     open(OUT, ">in0") || die;
  145.     while (<IN>) {
  146.         if (/^------../) {
  147.             chop;
  148.             $int = $_;
  149.             $int =~ s/^--------..//;
  150.             $int =~ s/-+//g;
  151.             if ($last eq $int) {
  152.                 $int .= $letter++;
  153.             } else {
  154.                 $letter = 'a';
  155.                 $last = $int;
  156.             }
  157.         }
  158.         if (/^INT /) {
  159.             chop;
  160.             $line = $_;
  161.             $line =~ s/^INT [^-]*- //;
  162.             $line =~ s/\\/\\\\/g;
  163.             print OUT "$line\`$int\n";
  164.         }
  165.     }
  166.     close(IN);
  167.     close(OUT);
  168. }
  169.  
  170. # Return a unique new label
  171. sub newlabel
  172. {
  173.     return "\@IL" . $labelnum++;
  174. }
  175.  
  176. # Unlink all output files
  177. sub unlink_out
  178. {
  179.     for ($i = 0; $i < 10; $i++) {
  180.         unlink("out$i");
  181.     }
  182. }
  183.  
  184. # Unlink all intermediate files
  185. sub unlink_intermediate
  186. {
  187.     for ($i = 0; $i < 10; $i++) {
  188.         unlink("out$i");
  189.         unlink("in$i");
  190.     }
  191.     unlink('sum.byf');
  192.     unlink('sum.byv');
  193. }
  194.  
  195. # Merge the output files into int.byf
  196. sub merge_out
  197. {
  198.     local($outname) = @_;
  199.  
  200.     open(OUT, ">$outname");
  201.     for ($i = 0; $i < 10; $i++) {
  202.         if (open(IN, "out$i")) {
  203.             while (<IN>) {
  204.                 print OUT;
  205.             }
  206.             close(IN);
  207.         }
  208.     }
  209.     close(OUT);
  210.     &unlink_out();
  211. }
  212.  
  213. # Open the interrupt list and create a file with one line for each
  214. # interrupt.  The line consists of the interrupt identifications
  215. # (number and register values) followed by the unique interrupt identifier
  216. sub maketop_by_value
  217. {
  218.     &unlink_out();
  219.     open(IN, "interrup.lst") || die;
  220.     open(OUT, ">in0") || die;
  221.     while (<IN>) {
  222.         if (/^--------..[0-9A-F]/) {
  223.             chop;
  224.             $int = $_;
  225.             $int =~ s/^--------..//;
  226.             $int =~ s/-+//g;
  227.             if ($last eq $int) {
  228.                 $int .= $letter++;
  229.             } else {
  230.                 $letter = 'a';
  231.                 $last = $int;
  232.             }
  233.             $_ =~ /^--------..(..)(..)(..)(..)(....)/;
  234.             $num = $1;    # Interrupt number
  235.             $ah = $2;    # Register AH
  236.             $al = $3;    # Register AL
  237.             $rn = $4;    # Other register name
  238.             $rv = $5;    # Other register value (8 or 16 bit)
  239.             $rv =~ s/-//g;
  240.             print OUT "INT $num";
  241.             print OUT " - AH = $ah" if ($ah ne '--');
  242.             print OUT " - AL = $al" if ($al ne '--');
  243.             print OUT " - $rn = $rv" if ($rn ne '--');
  244.             print OUT "`$int\n";
  245.         }
  246.     }
  247.     close(IN);
  248.     close(OUT);
  249. }
  250.  
  251. # Create the bottom nodes of the file
  252. # Each node contains a navigation line for going upwards by value or function
  253. # Try to create seens for the SeeAlso lines
  254. sub makebottom
  255. {
  256.     open(IN, "interrup.lst") || die;
  257.     open(OUT, ">int.bot") || die;
  258.     print OUT &makehead('int.intro', 3, 'Interrupt List', 'int.hlp');
  259.     while (<IN>) {
  260.         chop;
  261.         s/\\/\\\\/g;
  262.         if (/^--------..[0-9A-F]/) {
  263.             $int = $_;
  264.             $int =~ s/^--------..//;
  265.             $int =~ s/-+//g;
  266.             if ($last eq $int) {
  267.                 $int .= $letter++;
  268.             } else {
  269.                 $letter = 'a';
  270.                 $last = $int;
  271.             }
  272.             $_ =~ /^--------..(..)(..)(..)(..)(....)/;
  273.             $num = $1;    # Interrupt number
  274.         } elsif (/^INT /) {
  275.             $line = $_;
  276.             print "$line\n";
  277.             print OUT ' ' x 35 . "-\04-\n";
  278.             print OUT ".context $int\n";
  279.             print OUT ".freeze 4\n";
  280.             print OUT ".topic $line\n";
  281.             $upf = &parent('sum.byf', $int);
  282.             $upv = &parent('sum.byv', $int);
  283.             print OUT "                         \\i\021\\p\\aUp Function\\v${upf}\\v\\i\020\\p \\i\021\\p\\aUp Value\\v${upv}\\v\\i\020\\p \\i\021\\p\\aContents\\vint.hlp\\v\\i\020\\p \\i\021\\p\\aIndex\\vint.idx\\v\\i\020\\p \\i\021\\p\\aBack\\v!B\\v\\i\020\\p\n";
  284.             print OUT "\304" x 75 . "\n";
  285.             print OUT "\\b$line\\p\n\n";
  286.         } elsif (/^SeeAlso: (.*)$/) {
  287.             print OUT '\bSeeAlso:\p ';
  288.             @back = @list = split(/, */, $1);
  289.             for ($i = 0; $i <= $#list; $i++) {
  290.                 $list[$i] =~ s/"[^"]*"//g;
  291.                 $list[$i] =~ s/A[HX]//g;
  292.                 $list[$i] =~ s/[\/h=]//g;
  293.                 if ($list[$i] =~ /^INT (..)/) {
  294.                     $num = $1;
  295.                     $list[$i] =~ s/^INT //;
  296.                 } else {
  297.                     $list[$i] =~ s/^/$num/;
  298.                 }
  299.                 if ($cont = &intcontext($list[$i])) {
  300.                     print OUT "\\i\021\\p\\a$back[$i]\\i\020\\p\\v$cont\\v";
  301.                 } elsif (&exists($list[$i])) {
  302.                     print OUT "\\i\021\\p\\a$back[$i]\\i\020\\p\\v$list[$i]\\v";
  303.                 } else {
  304.                     print OUT "$back[$i]";
  305.                 }
  306.                 print OUT ', ' if ($i < $#list);
  307.             }
  308.             print OUT "\n";
  309.         } elsif (/^(\w+:)(.*)$/) {
  310.             print OUT "\\b$1\\p$2\n";
  311.         } else {
  312.             print OUT;
  313.             print OUT "\n";
  314.         }
  315.     }
  316.     print OUT ' ' x 35 . "-\04-\n";
  317.     close(IN);
  318.     close(OUT);
  319. }
  320.  
  321. # Reding $in create a $out file containing each context and its parent
  322. # context.
  323. sub summary
  324. {
  325.     local($in, $out) = @_;
  326.  
  327.     open(IN, $in) || die;
  328.     open(OUT, ">$out") || die;
  329.     while (<IN>) {
  330.         chop;
  331.         next if (/\\i\021\\p/);
  332.         if (/^\.context (.*)$/) {
  333.             $context = $1;
  334.         }
  335.         if (/\\v([^I][^\\]+)/) {
  336.             print OUT "$1`$context\n";
  337.         }
  338.     }
  339. }
  340.  
  341. # Return the parent of node $val in file $in
  342. sub parent
  343. {
  344.     local ($in, $val) = @_;
  345.  
  346.     open (SUM, $in) || die;
  347.     while (<SUM>) {
  348.         chop;
  349.         if (/^$val`(.*)$/) {
  350.             close(SUM);
  351.             return $1;
  352.         }
  353.     }
  354.     print STDERR "\a*** $val has not parent node!\n";
  355.     close(SUM);
  356.     return 'int.hlp';
  357. }
  358.  
  359. # Return true if a bottom node $val exists as a context
  360. sub exists
  361. {
  362.     local ($val) = @_;
  363.  
  364.     open (EX, 'sum.byf') || die;
  365.     while (<EX>) {
  366.         chop;
  367.         if (/^$val`/) {
  368.             close(SUM);
  369.             return 1;
  370.         }
  371.     }
  372.     print STDERR "\a*** $val does not exist!\n";
  373.     close(SUM);
  374.     return 0;
  375. }
  376.  
  377. # Given a two digit interrupt number return the correct context
  378. # Works by searching the first 300 lines of int.byv.  Do not change
  379. # its format without checking this function.
  380. sub intcontext
  381. {
  382.     local($int) = @_;
  383.  
  384.     if ($int !~ /^[0-9][A-F][0-9][A-F]$/) {
  385.         return undef;
  386.     }
  387.     open(INC, 'int.byv') || die;
  388.     $i = 0;
  389.     while (<INC> && $i < 300) {
  390.         if (/\\aINT $int\\v([^\\]+)\\v$/) {
  391.             close(INC);
  392.             return $1;
  393.         }
  394.         $i++;
  395.     }
  396.     close(INC);
  397.     print STDERR "\a*** Unable to locate interrupt $int\n";
  398.     return undef;
  399. }
  400.  
  401. # Make a simple index by concatenating all the int.byf lines and sorting them
  402. # by character.
  403. sub makeindex
  404. {
  405.     # Construct the index line
  406.     $all='ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';        # Dict chars
  407.     $index = "\332";
  408.     for ($i = 0; $i < length($all) - 1; $i++) {
  409.         $index .= "\304\302";
  410.     }
  411.     $index .= "\304\277\n";
  412.     $index .= "\263";
  413.     for ($i = 0; $i < length($all); $i++) {
  414.         $l = substr($all, $i, 1);
  415.         $index .= "\\a$l\\v\@IL.$l\\v\263";
  416.     }
  417.     $index .= "\n";
  418.     $index .= "\300";
  419.     for ($i = 0; $i < length($all) - 1; $i++) {
  420.         $index .= "\304\301";
  421.     }
  422.     $index .= "\304\331\n\n";
  423.     # Now create the index, character by character
  424.     open(IN, 'sort -d -f int.byf|');    # Fold case, dict order
  425.     open(OUT, '>int.idx');
  426.     undef $prev;
  427.     while (<IN>) {
  428.         if (/^\t\\a[^A-Za-z0-9]*(.)/) {
  429.             $letter = $1;
  430.             next if ($letter eq '?');        # Ignore \v on V
  431.             $letter =~ tr/[a-z]/[A-Z]/;
  432.             if ($letter ne $prev) {
  433.                 print OUT ' ' x 35 . "-\04-\n" if ($prev);
  434.                 print OUT &makehead("\@IL.$letter", 7, "Index $letter", 'int.idx');
  435.                 $idxline = $index;
  436.                 $idxline =~ s/\\a$letter\\v/\\a\\b$letter\\p\\v/;
  437.                 print OUT $idxline;
  438.                 $prev = $letter;
  439.             }
  440.             print OUT;
  441.         }
  442.     }
  443.     close(IN);
  444.     print OUT ' ' x 35 . "-\04-\n";
  445.     print OUT ".context h.idx\n";
  446.     print OUT &makehead('int.idx', 3, 'Index', 'int.hlp');
  447.     print OUT "\n\n\n";
  448.     print OUT $index;
  449.     print OUT ' ' x 35 . "-\04-\n";
  450.     close(OUT);
  451. }
  452.  
  453. # Include a file with given context, topic and filename to the file int.fil
  454. sub incfile
  455. {
  456.     local($context, $topic, $name) = @_;
  457.  
  458.     open(OUT, '>>int.fil');
  459.     open(IN, "$name") || die;
  460.     print OUT &makehead($context, 3, $topic, 'int.hlp');
  461.     while (<IN>) {
  462.         s/\\/\\\\/g;
  463.         print OUT;
  464.     }
  465.     print OUT ' ' x 35 . "-\04-\n";
  466.     close(OUT);
  467. }
  468.  
  469. # Create the table of contents file
  470. sub maketoc
  471. {
  472.     open(OUT, '>int.toc') || die;
  473.     print OUT 
  474. ".context Interrupt List
  475. .context int.hlp
  476. .context int
  477. .context interrupt list
  478. .context h.contents
  479. .context h.pg1
  480. ";
  481.     print OUT &makehead('contents', 3, 'The Interrupt List', 'int.hlp');
  482.     print OUT "\t\t\t\\bThe PC Interrupt List\\p
  483.  
  484.  
  485. \t\\a\\i\021\\p1. General Information\\vint.1st\\v\\i\020\\p
  486. \t\\a\\i\021\\p2. File Header\\vint.intro\\v\\i\020\\p
  487. \t\\a\\i\021\\p3. Interrupts by Value\\vint.byval\\v\\i\020\\p
  488. \t\\a\\i\021\\p4. Interrupts by Function\\vint.byfunc\\v\\i\020\\p
  489. \t\\a\\i\021\\p5. Memory List\\vint.mem\\v\\i\020\\p
  490. \t\\a\\i\021\\p6. Interrupt Primer\\vint.pri\\v\\i\020\\p
  491. \t\\a\\i\021\\p7. Index\\vint.idx\\v\\i\020\\p
  492.  
  493.  
  494.  
  495.  
  496.  
  497. Compilation Copyright (c) 1989, 1990, 1991 Ralf Brown
  498. Helpmake conversion Copyright (c) 1991 Diomidis Spinellis
  499.  
  500.                                    -\04-
  501. .context List Categories
  502. Interrupt List
  503. ";
  504.     close(OUT);
  505. }
  506.  
  507. #
  508. # Split up the interrup.1st file into sections as section.1st
  509. #
  510. sub make1st
  511. {
  512.     open(IN, 'interrup.1st') || die;
  513.     open(OUT, '>>int.fil') || die;
  514.     @sections = (
  515.         'Version', &newlabel,
  516.         'Copyright Notice', &newlabel,
  517.         'Additional Copyright', &newlabel,
  518.         'Disclaimer', &newlabel,
  519.         'Updates and Distribution', &newlabel,
  520.         'System Abbreviations', &newlabel,
  521.         'Contributors', &newlabel,
  522.         'Sources', &newlabel,
  523.         'API Reference Providers', &newlabel,
  524.         'Other Addresses', &newlabel,
  525.         'Trademarks and Copyrights', &newlabel,
  526.         'Reviews', &newlabel,
  527.         'Author Contact', &newlabel
  528.     );
  529.     for ($i = 0; $i <= $#sections; $i += 2) {
  530.         print OUT &makehead($sections[$i + 1], 3, $sections[$i], 'int.1st');
  531.         while (<IN>) {
  532.             last if (/^----------------------------------/);
  533.             s/\\/\\\\/g;
  534.             print OUT;
  535.         }
  536.         print OUT ' ' x 35 . "-\04-\n";
  537.     }
  538.     print OUT &makehead('int.1st', 3, 'General Information', 'int.hlp');
  539.     print OUT "\t\t\t\t\\bGeneral Information\\p\n\n\n";
  540.     for ($i = 0, $num = 1; $i <= $#sections; $i += 2, $num++) {
  541.         printf(OUT "\t\\a\\i\021\\p%2d. $sections[$i]\\v" . $sections[$i + 1] . "\\v\\i\020\\p\n", $num);
  542.     }
  543.     print OUT "\n\n";
  544.     print OUT ' ' x 35 . "-\04-\n";
  545.     close(OUT);
  546. }
  547.  
  548. #
  549. # Return a navigation head for an entry
  550. #
  551. sub makehead
  552. {
  553.     local($context, $freeze, $topic, $up) = @_;
  554.     $head = ".context $context\n";
  555.     $head .= ".freeze $freeze\n";
  556.     $head .= ".topic $topic\n";
  557.     $head .= "                                             \\i\021\\p\\aUp\\v${up}\\v\\i\020\\p \\i\021\\p\\aContents\\vint.hlp\\v\\i\020\\p \\i\021\\p\\aIndex\\vint.idx\\v\\i\020\\p \\i\021\\p\\aBack\\v!B\\v\\i\020\\p\n";
  558.     $head .= "\304" x 75 . "\n\n";
  559.     return $head;
  560. }
  561.